﻿using System;
using System.Linq;
using Csla;
using Csla.Data;
using Csla.Serialization;
using BizControl.DalLinq;
using BizControl.Library.BusinessObjects.People;
using BizControl.Library.BusinessObjects.Models;
using BizControl.Library.Criterias;
using BizControl.Library.Security;
using BizControl.Resources;
using System.Security;

namespace BizControl.Library.BusinessObjects.BusinessRoles
{
  [Serializable()]
  public class BusinessRoleList : DynamicListBase<BusinessRoleBO>
  {
    #region  Business Methods

    private ModelBO _model;

    public BusinessRoleBO this[Guid roleIdSearchFor]
    {
      get
      {
        foreach (BusinessRoleBO role in this)
        {
          if (role.RoleId == roleIdSearchFor)
            return role;
        }
        return null;
      }
    }

    public BusinessRoleBO this[BusinessRoleInfo roleInfoSearchFor]
    {
      get
      {
        foreach (BusinessRoleBO role in this)
        {
          if (role.RoleId == roleInfoSearchFor.Id)
            return role;
        }
        return null;
      }
    }

    public BusinessRoleBO AddRole()
    {
      if (null != _model)
      {
        BusinessRoleBO role = BusinessRoleBO.NewBusinessRole(_model);
        this.Add(role);
        return role;
      }
      else
      {
        throw new InvalidOperationException(ExceptionsMessages.ModelIsNotSetAddRoleFail);
      }
    }

    public void Remove(Guid roleId)
    {
      foreach (BusinessRoleBO role in this)
      {
        if (role.RoleId == roleId)
        {
          Remove(role);
          break;
        }
      }
    }

    public bool Contains(Guid roleId)
    {
      foreach (BusinessRoleBO role in this)
        if (role.RoleId == roleId)
          return true;
      return false;
    }

    #endregion

    #region  Factory Methods

    public static BusinessRoleList GetBusinessRoleList(ModelBO model, bool includeEmptyRole = false)
    {
      return DataPortal.Fetch<BusinessRoleList>(new ModelAndBoolCriteria(model, includeEmptyRole));
    }

    public static BusinessRoleList GetBusinessRoleList(bool includeEmptyRole = false)
    {
      var model = SecurityChecks.GetCurrentModel();
      return DataPortal.Fetch<BusinessRoleList>(new ModelAndBoolCriteria(model, includeEmptyRole));
    }

    #endregion

    #region  Data Access

    private void DataPortal_Create(ModelBO model)
    {
      if (null == model) throw new ArgumentNullException(ExceptionsMessages.ModelNullReference);
      _model = model;
    }

    private void DataPortal_Fetch(ModelAndBoolCriteria criteria)
    {
      Fetch(criteria);
    }

    private void Fetch(ModelAndBoolCriteria criteria)
    {
      if (null == criteria.Model) throw new ArgumentNullException(ExceptionsMessages.ModelNullReference);
      _model = criteria.Model;
      RaiseListChangedEvents = false;
      using (var ctx = ContextManager<BusinessControl2DataContext>.GetManager(Database.BizControlDB))
      {
        var data = from r in ctx.DataContext.BusinessRoles
                   where !r.IsDeleted && r.Model == criteria.Model.ModelId
                   select BusinessRoleBO.GetBusinessRole(r.RoleId);
        this.AddRange(data);
      }
      if (criteria.IncludeEmptyObject)
        this.Add(BusinessRoleBO.GetEmptyRole());
      RaiseListChangedEvents = true;
    }

    #endregion

  }
}